/*
 * Copyright (C) 2010-2011 ProjectSkyfire <http://www.projectskyfire.org/>
 * 
 * Copyright (C) 2011 ArkCORE <http://www.arkania.net/>
 * Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Scripts for spells with SPELLFAMILY_GENERIC spells used by items.
 * Ordered alphabetically using scriptname.
 * Scriptnames of files in this file should be prefixed with "spell_item_".
 */

#include "ScriptPCH.h"
#include "SkillDiscovery.h"

// Generic script for handling item dummy effects which trigger another spell.
class spell_item_trigger_spell: public SpellScriptLoader {
private:
	uint32 _triggeredSpellId;

public:
	spell_item_trigger_spell(const char* name, uint32 triggeredSpellId) :
			SpellScriptLoader(name), _triggeredSpellId(triggeredSpellId) {
	}

	class spell_item_trigger_spell_SpellScript: public SpellScript {
		PrepareSpellScript(spell_item_trigger_spell_SpellScript)
	private:
		uint32 _triggeredSpellId;

	public:
		spell_item_trigger_spell_SpellScript(uint32 triggeredSpellId) :
				SpellScript(), _triggeredSpellId(triggeredSpellId) {
		}

		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(_triggeredSpellId))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			if (Item* pItem = GetCastItem())
				GetCaster()->CastSpell(GetCaster(), _triggeredSpellId, true,
						pItem);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_trigger_spell_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_trigger_spell_SpellScript(_triggeredSpellId);
	}
};

// http://www.wowhead.com/item=6522 Deviate Fish
// 8063 Deviate Fish
enum eDeviateFishSpells {
	SPELL_SLEEPY = 8064,
	SPELL_INVIGORATE = 8065,
	SPELL_SHRINK = 8066,
	SPELL_PARTY_TIME = 8067,
	SPELL_HEALTHY_SPIRIT = 8068,
};

class spell_item_deviate_fish: public SpellScriptLoader {
public:
	spell_item_deviate_fish() :
			SpellScriptLoader("spell_item_deviate_fish") {
	}

	class spell_item_deviate_fish_SpellScript: public SpellScript {
		PrepareSpellScript(spell_item_deviate_fish_SpellScript)
	public:
		bool Validate(SpellEntry const * /*spellEntry*/) {
			for (uint32 spellId = SPELL_SLEEPY; spellId <= SPELL_HEALTHY_SPIRIT;
					++spellId)
				if (!sSpellStore.LookupEntry(spellId))
					return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			Unit* pCaster = GetCaster();
			if (pCaster->GetTypeId() != TYPEID_PLAYER)
				return;

			uint32 spellId = urand(SPELL_SLEEPY, SPELL_HEALTHY_SPIRIT);
			pCaster->CastSpell(pCaster, spellId, true, NULL);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_deviate_fish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_deviate_fish_SpellScript();
	}
};

// http://www.wowhead.com/item=47499 Flask of the North
// 67019 Flask of the North
enum eFlaskOfTheNorthSpells {
	SPELL_FLASK_OF_THE_NORTH_SP = 67016,
	SPELL_FLASK_OF_THE_NORTH_AP = 67017,
	SPELL_FLASK_OF_THE_NORTH_STR = 67018,
};

class spell_item_flask_of_the_north: public SpellScriptLoader {
public:
	spell_item_flask_of_the_north() :
			SpellScriptLoader("spell_item_flask_of_the_north") {
	}

	class spell_item_flask_of_the_north_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_flask_of_the_north_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_FLASK_OF_THE_NORTH_SP))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_FLASK_OF_THE_NORTH_AP))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_FLASK_OF_THE_NORTH_STR))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			Unit* pCaster = GetCaster();
			if (pCaster->GetTypeId() != TYPEID_PLAYER)
				return;

			std::vector<uint32> possibleSpells;
			switch (pCaster->getClass()) {
			case CLASS_WARLOCK:
			case CLASS_MAGE:
			case CLASS_PRIEST:
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP);
				break;
			case CLASS_DEATH_KNIGHT:
			case CLASS_WARRIOR:
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR);
				break;
			case CLASS_ROGUE:
			case CLASS_HUNTER:
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP);
				break;
			case CLASS_DRUID:
			case CLASS_PALADIN:
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP);
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_STR);
				break;
			case CLASS_SHAMAN:
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_SP);
				possibleSpells.push_back(SPELL_FLASK_OF_THE_NORTH_AP);
				break;
			}

			pCaster->CastSpell(pCaster,
					possibleSpells[irand(0, (possibleSpells.size() - 1))], true,
					NULL);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_flask_of_the_north_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_flask_of_the_north_SpellScript();
	}
};

// http://www.wowhead.com/item=10645 Gnomish Death Ray
// 13280 Gnomish Death Ray
enum eGnomishDeathRay {
	SPELL_GNOMISH_DEATH_RAY_SELF = 13493, SPELL_GNOMISH_DEATH_RAY_TARGET = 13279,
};

class spell_item_gnomish_death_ray: public SpellScriptLoader {
public:
	spell_item_gnomish_death_ray() :
			SpellScriptLoader("spell_item_gnomish_death_ray") {
	}

	class spell_item_gnomish_death_ray_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_gnomish_death_ray_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_GNOMISH_DEATH_RAY_SELF))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_GNOMISH_DEATH_RAY_TARGET))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			if (Unit* pTarget = GetHitUnit()) {
				Unit* pCaster = GetCaster();
				if (urand(0, 99) < 15)
					pCaster->CastSpell(pCaster, SPELL_GNOMISH_DEATH_RAY_SELF,
							true, NULL); // failure
				else
					pCaster->CastSpell(pTarget, SPELL_GNOMISH_DEATH_RAY_TARGET,
							true, NULL);
			}
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_gnomish_death_ray_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_gnomish_death_ray_SpellScript();
	}
};

// http://www.wowhead.com/item=27388 Mr. Pinchy
// 33060 Make a Wish
enum eMakeAWish {
	SPELL_MR_PINCHYS_BLESSING = 33053,
	SPELL_SUMMON_MIGHTY_MR_PINCHY = 33057,
	SPELL_SUMMON_FURIOUS_MR_PINCHY = 33059,
	SPELL_TINY_MAGICAL_CRAWDAD = 33062,
	SPELL_MR_PINCHYS_GIFT = 33064,
};

class spell_item_make_a_wish: public SpellScriptLoader {
public:
	spell_item_make_a_wish() :
			SpellScriptLoader("spell_item_make_a_wish") {
	}

	class spell_item_make_a_wish_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_make_a_wish_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_MR_PINCHYS_BLESSING))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_SUMMON_MIGHTY_MR_PINCHY))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_SUMMON_FURIOUS_MR_PINCHY))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_TINY_MAGICAL_CRAWDAD))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_MR_PINCHYS_GIFT))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			Unit* pCaster = GetCaster();
			if (pCaster->GetTypeId() != TYPEID_PLAYER)
				return;

			uint32 spellId = SPELL_MR_PINCHYS_GIFT;
			switch (urand(1, 5)) {
			case 1:
				spellId = SPELL_MR_PINCHYS_BLESSING;
				break;
			case 2:
				spellId = SPELL_SUMMON_MIGHTY_MR_PINCHY;
				break;
			case 3:
				spellId = SPELL_SUMMON_FURIOUS_MR_PINCHY;
				break;
			case 4:
				spellId = SPELL_TINY_MAGICAL_CRAWDAD;
				break;
			}
			pCaster->CastSpell(pCaster, spellId, true, NULL);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_make_a_wish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_make_a_wish_SpellScript();
	}
};

// http://www.wowhead.com/item=32686 Mingo's Fortune Giblets
// 40802 Mingo's Fortune Generator
class spell_item_mingos_fortune_generator: public SpellScriptLoader {
public:
	spell_item_mingos_fortune_generator() :
			SpellScriptLoader("spell_item_mingos_fortune_generator") {
	}

	class spell_item_mingos_fortune_generator_SpellScript: public SpellScript {
		PrepareSpellScript(spell_item_mingos_fortune_generator_SpellScript)
		void HandleDummy(SpellEffIndex effIndex) {
			// Selecting one from Bloodstained Fortune item
			uint32 newitemid;
			switch (urand(1, 20)) {
			case 1:
				newitemid = 32688;
				break;
			case 2:
				newitemid = 32689;
				break;
			case 3:
				newitemid = 32690;
				break;
			case 4:
				newitemid = 32691;
				break;
			case 5:
				newitemid = 32692;
				break;
			case 6:
				newitemid = 32693;
				break;
			case 7:
				newitemid = 32700;
				break;
			case 8:
				newitemid = 32701;
				break;
			case 9:
				newitemid = 32702;
				break;
			case 10:
				newitemid = 32703;
				break;
			case 11:
				newitemid = 32704;
				break;
			case 12:
				newitemid = 32705;
				break;
			case 13:
				newitemid = 32706;
				break;
			case 14:
				newitemid = 32707;
				break;
			case 15:
				newitemid = 32708;
				break;
			case 16:
				newitemid = 32709;
				break;
			case 17:
				newitemid = 32710;
				break;
			case 18:
				newitemid = 32711;
				break;
			case 19:
				newitemid = 32712;
				break;
			case 20:
				newitemid = 32713;
				break;
			default:
				return;
			}

			CreateItem(effIndex, newitemid);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_mingos_fortune_generator_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_mingos_fortune_generator_SpellScript();
	}
};

// http://www.wowhead.com/item=10720 Gnomish Net-o-Matic Projector
// 13120 Net-o-Matic
enum eNetOMaticSpells {
	SPELL_NET_O_MATIC_TRIGGERED1 = 16566,
	SPELL_NET_O_MATIC_TRIGGERED2 = 13119,
	SPELL_NET_O_MATIC_TRIGGERED3 = 13099,
};

class spell_item_net_o_matic: public SpellScriptLoader {
public:
	spell_item_net_o_matic() :
			SpellScriptLoader("spell_item_net_o_matic") {
	}

	class spell_item_net_o_matic_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_net_o_matic_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_NET_O_MATIC_TRIGGERED1))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_NET_O_MATIC_TRIGGERED2))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_NET_O_MATIC_TRIGGERED3))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			if (Unit* pTarget = GetHitUnit()) {
				uint32 spellId = SPELL_NET_O_MATIC_TRIGGERED3;
				uint32 roll = urand(0, 99);
				if (roll < 2) // 2% for 30 sec self root (off-like chance unknown)
					spellId = SPELL_NET_O_MATIC_TRIGGERED1;
				else if (roll < 4) // 2% for 20 sec root, charge to target (off-like chance unknown)
					spellId = SPELL_NET_O_MATIC_TRIGGERED2;

				GetCaster()->CastSpell(pTarget, spellId, true, NULL);
			}
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_net_o_matic_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_net_o_matic_SpellScript();
	}
};

// http://www.wowhead.com/item=8529 Noggenfogger Elixir
// 16589 Noggenfogger Elixir
enum eNoggenfoggerElixirSpells {
	SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1 = 16595,
	SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2 = 16593,
	SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3 = 16591,
};

class spell_item_noggenfogger_elixir: public SpellScriptLoader {
public:
	spell_item_noggenfogger_elixir() :
			SpellScriptLoader("spell_item_noggenfogger_elixir") {
	}

	class spell_item_noggenfogger_elixir_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_noggenfogger_elixir_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			Unit* pCaster = GetCaster();
			if (pCaster->GetTypeId() != TYPEID_PLAYER)
				return;

			uint32 spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3;
			switch (urand(1, 3)) {
			case 1:
				spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1;
				break;
			case 2:
				spellId = SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2;
				break;
			}

			pCaster->CastSpell(pCaster, spellId, true, NULL);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_noggenfogger_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_noggenfogger_elixir_SpellScript();
	}
};

// http://www.wowhead.com/item=6657 Savory Deviate Delight
// 8213 Savory Deviate Delight
enum eSavoryDeviateDelight {
	SPELL_FLIP_OUT_MALE = 8219,
	SPELL_FLIP_OUT_FEMALE = 8220,
	SPELL_YAAARRRR_MALE = 8221,
	SPELL_YAAARRRR_FEMALE = 8222,
};

class spell_item_savory_deviate_delight: public SpellScriptLoader {
public:
	spell_item_savory_deviate_delight() :
			SpellScriptLoader("spell_item_savory_deviate_delight") {
	}

	class spell_item_savory_deviate_delight_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_savory_deviate_delight_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			for (uint32 spellId = SPELL_FLIP_OUT_MALE;
					spellId <= SPELL_YAAARRRR_FEMALE; ++spellId)
				if (!sSpellStore.LookupEntry(spellId))
					return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			Unit* pCaster = GetCaster();
			if (pCaster->GetTypeId() != TYPEID_PLAYER)
				return;

			uint32 spellId = 0;
			switch (urand(1, 2)) {
			// Flip Out - ninja
			case 1:
				spellId = (
						pCaster->getGender() == GENDER_MALE ?
								SPELL_FLIP_OUT_MALE : SPELL_FLIP_OUT_FEMALE);
				break;
				// Yaaarrrr - pirate
			case 2:
				spellId = (
						pCaster->getGender() == GENDER_MALE ?
								SPELL_YAAARRRR_MALE : SPELL_YAAARRRR_FEMALE);
				break;
			}
			pCaster->CastSpell(pCaster, spellId, true, NULL);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_savory_deviate_delight_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_savory_deviate_delight_SpellScript();
	}
};

// http://www.wowhead.com/item=7734 Six Demon Bag
// 14537 Six Demon Bag
enum eSixDemonBagSpells {
	SPELL_FROSTBOLT = 11538,
	SPELL_POLYMORPH = 14621,
	SPELL_SUMMON_FELHOUND_MINION = 14642,
	SPELL_FIREBALL = 15662,
	SPELL_CHAIN_LIGHTNING = 21179,
	SPELL_ENVELOPING_WINDS = 25189,
};

class spell_item_six_demon_bag: public SpellScriptLoader {
public:
	spell_item_six_demon_bag() :
			SpellScriptLoader("spell_item_six_demon_bag") {
	}

	class spell_item_six_demon_bag_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_six_demon_bag_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_FROSTBOLT))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_POLYMORPH))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_SUMMON_FELHOUND_MINION))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_FIREBALL))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_CHAIN_LIGHTNING))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_ENVELOPING_WINDS))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			if (Unit* pTarget = GetHitUnit()) {
				Unit* pCaster = GetCaster();

				uint32 spellId = 0;
				uint32 rand = urand(0, 99);
				if (rand < 25) // Fireball (25% chance)
					spellId = SPELL_FIREBALL;
				else if (rand < 50) // Frostball (25% chance)
					spellId = SPELL_FROSTBOLT;
				else if (rand < 70) // Chain Lighting (20% chance)
					spellId = SPELL_CHAIN_LIGHTNING;
				else if (rand < 80) // Polymorph (10% chance)
						{
					spellId = SPELL_POLYMORPH;
					if (urand(0, 100) <= 30) // 30% chance to self-cast
						pTarget = pCaster;
				} else if (rand < 95) // Enveloping Winds (15% chance)
					spellId = SPELL_ENVELOPING_WINDS;
				else // Summon Felhund minion (5% chance)
				{
					spellId = SPELL_SUMMON_FELHOUND_MINION;
					pTarget = pCaster;
				}

				pCaster->CastSpell(pTarget, spellId, true, GetCastItem());
			}
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_six_demon_bag_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_six_demon_bag_SpellScript();
	}
};

// http://www.wowhead.com/item=44012 Underbelly Elixir
// 59640 Underbelly Elixir
enum eUnderbellyElixirSpells {
	SPELL_UNDERBELLY_ELIXIR_TRIGGERED1 = 59645,
	SPELL_UNDERBELLY_ELIXIR_TRIGGERED2 = 59831,
	SPELL_UNDERBELLY_ELIXIR_TRIGGERED3 = 59843,
};

class spell_item_underbelly_elixir: public SpellScriptLoader {
public:
	spell_item_underbelly_elixir() :
			SpellScriptLoader("spell_item_underbelly_elixir") {
	}

	class spell_item_underbelly_elixir_SpellScript: public SpellScript {
	public:
		PrepareSpellScript(spell_item_underbelly_elixir_SpellScript)
		bool Validate(SpellEntry const * /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_UNDERBELLY_ELIXIR_TRIGGERED1))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_UNDERBELLY_ELIXIR_TRIGGERED2))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_UNDERBELLY_ELIXIR_TRIGGERED3))
				return false;
			return true;
		}

		void HandleDummy(SpellEffIndex /*effIndex*/) {
			Unit* pCaster = GetCaster();
			if (pCaster->GetTypeId() != TYPEID_PLAYER)
				return;

			uint32 spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED3;
			switch (urand(1, 3)) {
			case 1:
				spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED1;
				break;
			case 2:
				spellId = SPELL_UNDERBELLY_ELIXIR_TRIGGERED2;
				break;
			}
			pCaster->CastSpell(pCaster, spellId, true, NULL);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_underbelly_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_underbelly_elixir_SpellScript();
	}
};

enum eShadowmourneVisuals {
	SPELL_SHADOWMOURNE_VISUAL_LOW = 72521,
	SPELL_SHADOWMOURNE_VISUAL_HIGH = 72523,
	SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF = 73422,
};

class spell_item_shadowmourne: public SpellScriptLoader {
public:
	spell_item_shadowmourne() :
			SpellScriptLoader("spell_item_shadowmourne") {
	}

	class spell_item_shadowmourne_AuraScript: public AuraScript {
	public:
		PrepareAuraScript(spell_item_shadowmourne_AuraScript)
		spell_item_shadowmourne_AuraScript() :
				AuraScript() {
		}

		bool Validate(SpellEntry const* /*spellEntry*/) {
			if (!sSpellStore.LookupEntry(SPELL_SHADOWMOURNE_VISUAL_LOW))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_SHADOWMOURNE_VISUAL_HIGH))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF))
				return false;
			return true;
		}

		void OnStackChange(AuraEffect const* /*aurEff*/,
				AuraEffectHandleModes /*mode*/) {
			Unit* target = GetTarget();

			switch (GetStackAmount()) {
			case 1:
				target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_LOW, true);
				break;
			case 6:
				target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW);
				target->CastSpell(target, SPELL_SHADOWMOURNE_VISUAL_HIGH, true);
				break;
			case 10:
				target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH);
				target->CastSpell(target, SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF,
						true);
				break;
			}
		}

		void OnRemove(AuraEffect const* /*aurEff*/,
				AuraEffectHandleModes /*mode*/) {
			Unit* target = GetTarget();

			if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_STACK)
				return;
			target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_LOW);
			target->RemoveAurasDueToSpell(SPELL_SHADOWMOURNE_VISUAL_HIGH);
		}

		void Register() {
			OnEffectApply +=
					AuraEffectApplyFn(spell_item_shadowmourne_AuraScript::OnStackChange, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL);
			OnEffectRemove +=
					AuraEffectRemoveFn(spell_item_shadowmourne_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_REAL);
		}
	};

	AuraScript* GetAuraScript() const {
		return new spell_item_shadowmourne_AuraScript();
	}
};

enum AirRifleSpells {
	SPELL_AIR_RIFLE_HOLD_VISUAL = 65582,
	SPELL_AIR_RIFLE_SHOOT = 67532,
	SPELL_AIR_RIFLE_SHOOT_SELF = 65577,
};

class spell_item_red_rider_air_rifle: public SpellScriptLoader {
public:
	spell_item_red_rider_air_rifle() :
			SpellScriptLoader("spell_item_red_rider_air_rifle") {
	}

	class spell_item_red_rider_air_rifle_SpellScript: public SpellScript {
		PrepareSpellScript(spell_item_red_rider_air_rifle_SpellScript)
		;

		bool Validate(SpellEntry const* /*spell*/) {
			if (!sSpellStore.LookupEntry(SPELL_AIR_RIFLE_HOLD_VISUAL))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_AIR_RIFLE_SHOOT))
				return false;
			if (!sSpellStore.LookupEntry(SPELL_AIR_RIFLE_SHOOT_SELF))
				return false;
			return true;
		}

		void HandleScript(SpellEffIndex effIndex) {
			PreventHitDefaultEffect(effIndex);
			if (!GetHitUnit())
				return;

			GetCaster()->CastSpell(GetCaster(), SPELL_AIR_RIFLE_HOLD_VISUAL,
					true);
			// needed because this spell shares GCD with its triggered spells (which must not be cast with triggered flag)
			if (Player* player = GetCaster()->ToPlayer())
				player->RemoveGlobalCooldown(GetSpellInfo());
			if (urand(0, 4))
				GetCaster()->CastSpell(GetHitUnit(), SPELL_AIR_RIFLE_SHOOT,
						false);
			else
				GetCaster()->CastSpell(GetCaster(), SPELL_AIR_RIFLE_SHOOT_SELF,
						false);
		}

		void Register() {
			OnEffect +=
					SpellEffectFn(spell_item_red_rider_air_rifle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_red_rider_air_rifle_SpellScript();
	}
};

class spell_item_book_of_glyph_mastery: public SpellScriptLoader {
public:
	spell_item_book_of_glyph_mastery() :
			SpellScriptLoader("spell_item_book_of_glyph_mastery") {
	}

	class spell_item_book_of_glyph_mastery_SpellScript: public SpellScript {
		PrepareSpellScript(spell_item_book_of_glyph_mastery_SpellScript)
		;

		SpellCastResult CheckRequirement() {
			if (GetCaster()->GetTypeId() == TYPEID_PLAYER
					&& HasDiscoveredAllSpells(GetSpellInfo()->Id,
							GetCaster()->ToPlayer())) {
				SetCustomCastResultMessage(
						SPELL_CUSTOM_ERROR_LEARNED_EVERYTHING);
				return SPELL_FAILED_CUSTOM_ERROR;
			}

			return SPELL_CAST_OK;
		}

		void Register() {
			OnCheckCast +=
					SpellCheckCastFn(spell_item_book_of_glyph_mastery_SpellScript::CheckRequirement);
		}
	};

	SpellScript* GetSpellScript() const {
		return new spell_item_book_of_glyph_mastery_SpellScript();
	}
};

enum eGenericData {
	SPELL_ARCANITE_DRAGONLING = 19804,
	SPELL_BATTLE_CHICKEN = 13166,
	SPELL_MECHANICAL_DRAGONLING = 4073,
	SPELL_MITHRIL_MECHANICAL_DRAGONLING = 12749,
};

void AddSC_item_spell_scripts() {
	// 23074 Arcanite Dragonling
	new spell_item_trigger_spell("spell_item_arcanite_dragonling",
			SPELL_ARCANITE_DRAGONLING);
	// 23133 Gnomish Battle Chicken
	new spell_item_trigger_spell("spell_item_gnomish_battle_chicken",
			SPELL_BATTLE_CHICKEN);
	// 23076 Mechanical Dragonling
	new spell_item_trigger_spell("spell_item_mechanical_dragonling",
			SPELL_MECHANICAL_DRAGONLING);
	// 23075 Mithril Mechanical Dragonling
	new spell_item_trigger_spell("spell_item_mithril_mechanical_dragonling",
			SPELL_MITHRIL_MECHANICAL_DRAGONLING);

	new spell_item_deviate_fish();
	new spell_item_flask_of_the_north();
	new spell_item_gnomish_death_ray();
	new spell_item_make_a_wish();
	new spell_item_mingos_fortune_generator();
	new spell_item_net_o_matic();
	new spell_item_noggenfogger_elixir();
	new spell_item_savory_deviate_delight();
	new spell_item_six_demon_bag();
	new spell_item_underbelly_elixir();
	new spell_item_shadowmourne();
	new spell_item_red_rider_air_rifle();
	new spell_item_book_of_glyph_mastery();
}
